/*
 * util.c
 *
 *  Created on: Apr 21, 2014
 *      Author: mitchellalpert
 */

#include <ctype.h>
#include <string.h>
#include "util.h"

int getNextToken(FILE* stream, char* buffer, int maxLength) {
	int read = 0;
	int c;

	while (read < maxLength) {
		/* Skip whitespace. */
		do {
			c = fgetc(stream);
		} while (isspace(c) || c == ',' || c == '(' || c == ')');
		if (c == EOF)
			break;

		/* Check for a line comment. */
		if (c == '#') {
			/* Skip a line comment. */
			do {
				c = fgetc(stream);
			} while (c != '\n');
			if (c == EOF)
				break;
		} else {
			/* Read in the next token. */
			do {
				buffer[read++] = c;
				c = fgetc(stream);
			} while (read < maxLength && c != EOF && c != ',' && c != '#' && c != '(' && c != ')' && !isspace(c));
			if (c == '#')
				ungetc(c, stream);
			buffer[read] = 0;
			return read;
		}
	}
	return 0;
}

struct {
	const char * sym;
	instruction_info info;
} instructionMap[] = {{"add", {ADD, RTYPE, 3, 32}}, {"addi", {ADDI, ITYPE, 3, 8}},
                      {"and", {AND, RTYPE, 3, 36}}, {"andi", {ANDI, ITYPE, 3, 12}},
                      {"beq", {BEQ, ITYPE, 3, 4}}, {"bne", {BNE, ITYPE, 3, 5}},
                      {"j", {J, JTYPE, 1, 2}}, {"jal", {JAL, JTYPE, 1, 3}},
                      {"jr", {JR, RTYPE, 1, 8}}, {"lui", {LUI, ITYPE, 2, 15}},
                      {"lw", {LW, ITYPE, 3, 35}}, {"or", {OR, RTYPE, 3, 37}},
                      {"ori", {ORI, ITYPE, 3, 13}}, {"sll", {SLL, RTYPE, 3, 0}},
                      {"slt", {SLT, RTYPE, 3, 42}}, {"slti", {SLTI, ITYPE, 3, 10}},
                      {"sra", {SRA, RTYPE, 3, 3}}, {"srl", {SRL, RTYPE, 3, 2}},
                      {"sw", {SW, ITYPE, 3, 43}}, {"syscall", {SYSCALL, RTYPE, 0, 12}}};

instruction_info getInstructionInfo(const char* str) {
	int i;

	for (i = 0; i < 20; i++)
		if (strcmp(str, instructionMap[i].sym) == 0)
			return instructionMap[i].info;
}

